"""
配置管理模块
负责加载和管理系统配置
"""

import os
import yaml
from pathlib import Path
from typing import Dict, Any, Optional
from pydantic import BaseSettings, Field
from loguru import logger


class SystemConfig(BaseSettings):
    """系统基础配置"""
    name: str = "MeetingRecognition"
    version: str = "1.0.0"
    debug: bool = False
    log_level: str = "INFO"
    max_workers: int = 4


class ServerConfig(BaseSettings):
    """服务器配置"""
    host: str = "0.0.0.0"
    port: int = 8000
    reload: bool = False
    workers: int = 1


class VideoInputConfig(BaseSettings):
    """视频输入配置"""
    max_streams: int = 4
    default_fps: int = 30
    sampling_rate: int = 2
    supported_formats: list = ["mp4", "mkv", "avi", "mov"]
    rtsp_timeout: int = 30
    webrtc_timeout: int = 30
    buffer_size: int = 100


class YOLODetectionConfig(BaseSettings):
    """YOLO检测配置"""
    model_path: str = "models/yolov8s.onnx"
    confidence_threshold: float = 0.5
    iou_threshold: float = 0.7
    max_detections_per_frame: int = 10
    input_size: list = [640, 640]
    device: str = "CPU"
    openvino_device: str = "CPU"
    batch_size: int = 1


class OCRConfig(BaseSettings):
    """OCR配置"""
    use_gpu: bool = False
    use_angle_cls: bool = True
    use_space_char: bool = True
    lang: str = "ch"
    det_algorithm: str = "DB"
    rec_algorithm: str = "CRNN"
    batch_size: int = 8
    confidence_threshold: float = 0.6
    max_text_length: int = 1000


class QueueConfig(BaseSettings):
    """队列配置"""
    redis_url: str = "redis://localhost:6379/0"
    max_queue_size: int = 1000
    worker_concurrency: int = 4
    task_timeout: int = 300
    retry_attempts: int = 3


class PostProcessingConfig(BaseSettings):
    """后处理配置"""
    min_confidence: float = 0.6
    merge_time_window: int = 5
    text_similarity_threshold: float = 0.8
    max_text_length: int = 10000
    language_detection: bool = True


class StorageConfig(BaseSettings):
    """存储配置"""
    database_url: str = "sqlite:///data/meeting_records.db"
    backup_enabled: bool = True
    backup_interval: int = 3600
    max_backup_files: int = 10
    encryption_enabled: bool = False
    encryption_key: str = ""


class ExportConfig(BaseSettings):
    """导出配置"""
    output_dir: str = "exports"
    formats: list = ["markdown", "docx", "json"]
    template_dir: str = "templates"
    max_export_size: int = 100


class SecurityConfig(BaseSettings):
    """安全配置"""
    secret_key: str = "your-secret-key-here"
    access_token_expire_minutes: int = 30
    algorithm: str = "HS256"
    cors_origins: list = ["*"]
    cors_methods: list = ["GET", "POST", "PUT", "DELETE"]
    cors_headers: list = ["*"]


class MonitoringConfig(BaseSettings):
    """监控配置"""
    enable_metrics: bool = True
    metrics_port: int = 9090
    health_check_interval: int = 30
    performance_logging: bool = True
    memory_threshold: int = 2048
    cpu_threshold: int = 80


class ModelsConfig(BaseSettings):
    """模型路径配置"""
    yolo_model: str = "models/yolov8s.onnx"
    ocr_det_model: str = "models/ch_PP-OCRv4_det_infer"
    ocr_rec_model: str = "models/ch_PP-OCRv4_rec_infer"
    ocr_cls_model: str = "models/ch_ppocr_mobile_v2.0_cls_infer"


class DirectoriesConfig(BaseSettings):
    """目录配置"""
    data: str = "data"
    logs: str = "logs"
    models: str = "models"
    temp: str = "temp"
    exports: str = "exports"
    uploads: str = "uploads"


class Config:
    """主配置类"""
    
    def __init__(self, config_path: Optional[str] = None):
        self.config_path = config_path or "config/config.yaml"
        self._config_data = self._load_config()
        
        # 初始化各个配置模块
        self.system = SystemConfig(**self._config_data.get("system", {}))
        self.server = ServerConfig(**self._config_data.get("server", {}))
        self.video_input = VideoInputConfig(**self._config_data.get("video_input", {}))
        self.yolo_detection = YOLODetectionConfig(**self._config_data.get("yolo_detection", {}))
        self.ocr = OCRConfig(**self._config_data.get("ocr", {}))
        self.queue = QueueConfig(**self._config_data.get("queue", {}))
        self.post_processing = PostProcessingConfig(**self._config_data.get("post_processing", {}))
        self.storage = StorageConfig(**self._config_data.get("storage", {}))
        self.export = ExportConfig(**self._config_data.get("export", {}))
        self.security = SecurityConfig(**self._config_data.get("security", {}))
        self.monitoring = MonitoringConfig(**self._config_data.get("monitoring", {}))
        self.models = ModelsConfig(**self._config_data.get("models", {}))
        self.directories = DirectoriesConfig(**self._config_data.get("directories", {}))
        
        # 创建必要的目录
        self._create_directories()
    
    def _load_config(self) -> Dict[str, Any]:
        """加载配置文件"""
        try:
            config_file = Path(self.config_path)
            if not config_file.exists():
                logger.warning(f"配置文件不存在: {self.config_path}, 使用默认配置")
                return {}
            
            with open(config_file, 'r', encoding='utf-8') as f:
                config_data = yaml.safe_load(f)
                logger.info(f"成功加载配置文件: {self.config_path}")
                return config_data or {}
                
        except Exception as e:
            logger.error(f"加载配置文件失败: {e}")
            return {}
    
    def _create_directories(self):
        """创建必要的目录"""
        directories = [
            self.directories.data,
            self.directories.logs,
            self.directories.models,
            self.directories.temp,
            self.directories.exports,
            self.directories.uploads
        ]
        
        for directory in directories:
            Path(directory).mkdir(parents=True, exist_ok=True)
            logger.debug(f"确保目录存在: {directory}")
    
    def get(self, key: str, default: Any = None) -> Any:
        """获取配置值"""
        keys = key.split('.')
        value = self._config_data
        
        try:
            for k in keys:
                value = value[k]
            return value
        except (KeyError, TypeError):
            return default
    
    def reload(self):
        """重新加载配置"""
        logger.info("重新加载配置文件")
        self.__init__(self.config_path)


# 全局配置实例
config = Config()
